package com.wep.fence.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wep.fence.dto.RegionFenceInfoDTO;
import com.wep.fence.dto.RegionGeom;
import com.wep.fence.entity.RegionEntity;
import com.wep.fence.entity.RegionGeomEntity;
import com.wep.fence.geom.GeoMap;
import com.wep.fence.geom.GeoPoint;
import com.wep.fence.mapper.RegionGeomMapper;
import com.wep.fence.service.RegionGeomService;
import com.wep.fence.service.RegionService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-18
 */
@Slf4j
@Service
public class RegionGeomServiceImpl extends ServiceImpl<RegionGeomMapper, RegionGeomEntity> implements RegionGeomService {
    @Resource
    private RegionService regionService;

    @Resource
    private ResourceLoader resourceLoader;


    @Resource
    private ObjectMapper objectMapper;

    @Override
    public String drawRegionMap(String regionCode, Integer geomJsonType) {
        // 获取区域围栏信息
        RegionFenceInfoDTO areaFenceInfoDTO = getRegionFenceInfoDTO(regionCode, geomJsonType);
        GeoPoint centerGeoPoint = areaFenceInfoDTO.getCenterGeoPoint();
        GeoMap map = new GeoMap(areaFenceInfoDTO.getFeatureStr(), regionCode, centerGeoPoint, 9, GeoMap.MapStyle.Darkblue, 7, 18);

        String fileName = regionCode + "_" + UUID.randomUUID() + "_" + "map.html";
        String prefix = System.getProperty("user.dir") + "/doc/html/";
        File file = map.file(prefix, fileName);
        log.info(file.getAbsolutePath());

        return file.getAbsolutePath();
    }

    @Override
    public RegionGeom queryGeomByRegionCode(String regionCode, Integer geomJsonType) {
        RegionGeomEntity regionGeomEntity = this.queryRegionGeom(regionCode);
        if (regionGeomEntity == null) {
            throw new RuntimeException("区域围栏信息不存在");
        }
        String path;
        if (geomJsonType != null && geomJsonType == 1) {
            path = StrUtil.isEmpty(regionGeomEntity.getPath()) ? regionGeomEntity.getPath() : regionGeomEntity.getPathPartition();
        } else {
            path = regionGeomEntity.getPath();
        }
        RegionEntity regionEntity = regionService.getByCode(regionCode);
        if (ObjUtil.isEmpty(regionEntity)) {
            throw new RuntimeException("区域信息不存在");
        }
        String classPath = "classpath:" + path;
        try (InputStream inputStream = resourceLoader.getResource(classPath).getInputStream()) {
            RegionGeom regionGeom = objectMapper.readValue(inputStream, RegionGeom.class);
            regionGeom.setRegionCode(regionCode);
            regionGeom.setRegionName(regionEntity.getName());

            return regionGeom;
        } catch (Exception e) {
            throw new RuntimeException("区域围栏转化失败");
        }
    }

    private RegionFenceInfoDTO getRegionFenceInfoDTO(String regionCode, Integer geomJsonType) {
        RegionGeom regionGeom = queryGeomByRegionCode(regionCode, geomJsonType);
        List<RegionGeom.RegionFeature> regionFeatureList = regionGeom.getFeatures();
        RegionGeom.RegionFeature regionFeature = regionFeatureList.get(0);
        RegionGeom.RegionGeometry geometry = regionFeature.getGeometry();
        List<List<List<List<Double>>>> coordinates = geometry.getCoordinates();
        List<List<List<Double>>> coordinates_0 = coordinates.get(0);
        List<List<Double>> coordinates_0_0 = coordinates_0.get(0);

        List<GeoPoint> geoPointList = new ArrayList<>();
        for (List<Double> doubles : coordinates_0_0) {
            GeoPoint geoPoint = new GeoPoint(doubles.get(0), doubles.get(1));
            geoPointList.add(geoPoint);
        }

        RegionGeom.RegionProperties properties = regionFeature.getProperties();
        List<Double> centerList = properties.getCenter();
        GeoPoint centerGeoPoint;
        if (CollUtil.isNotEmpty(centerList)) {
            double longitude = centerList.get(0);
            double latitude = centerList.get(1);
            centerGeoPoint = new GeoPoint(longitude, latitude);
        } else {
            centerGeoPoint = new GeoPoint(coordinates_0_0.get(0).get(0), coordinates_0_0.get(0).get(1));
        }
        RegionFenceInfoDTO regionFenceInfoDTO = new RegionFenceInfoDTO();
        regionFenceInfoDTO.setRegionCode(regionCode);
        regionFenceInfoDTO.setRegionName(regionGeom.getRegionName());
        regionFenceInfoDTO.setFencePoints(geoPointList);
        regionFenceInfoDTO.setCenterGeoPoint(centerGeoPoint);
        regionFenceInfoDTO.setFeatureStr(JSON.toJSONString(regionFeatureList));
        return regionFenceInfoDTO;
    }

    public RegionGeomEntity queryRegionGeom(String regionCode) {
        return getById(regionCode);
    }
}
